package com.xnj.file_buffer_stream_demo;

import java.io.*;

/**
 *  copy文件效率对比
 * 字节输入输出流对比字节输入输出缓冲流
 */
public class CopyTimeTest {
    // 源文件地址 , 大小： 1.5G
    public static  final String  FILE_PATH = "D:/测试电影文件.mp4";
    // 目标地址
    public static final String PATH = "D:/";

    public static void main(String[] args) {
        // 方式一：复制十分慢，直接淘汰，不予考虑
//        copy01();
        // 方式二：速度极快，推荐使用
        copy02(); // 7秒  8KB -> 1300ms  32KB ->538ms
        // 方式三：速度较慢
//        copy03(); // 方式三：12秒
        // 方式四：速度极快，推荐使用
//        copy04(); // 方式四：804毫秒  8kb-> 769ms  32KB -> 386ms

        // 推荐使用方式四
        // 当调大缓冲字节数组的大小时，方式二和方式四的差距会越来越小
    }

    // 字节输入输出流以单个字节为单位复制文件
    public static void copy01(){
        long start = System.currentTimeMillis();

        try(
                FileInputStream fis = new FileInputStream(FILE_PATH);
                FileOutputStream fos = new FileOutputStream(PATH+"01.mp4");
        ){
            int b;
            while ((b = fis.read())!=-1){
                fos.write(b);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        long end = System.currentTimeMillis();
        System.out.println("方式一复制文件耗时："+(end-start)/1000.0 + "秒");
    }

    // 字节输入输出流以字节数组为单位复制文件
    public static void copy02(){
        long start = System.currentTimeMillis();

        try(
                FileInputStream fis = new FileInputStream(FILE_PATH);
                FileOutputStream fos = new FileOutputStream(PATH+"02.mp4");
        ){
            byte[] buffer = new byte[1024];
//            byte[] buffer = new byte[1024*8];//8KB
//            byte[] buffer = new byte[1024*32];//32KB测试
            int b;
            while ((b = fis.read(buffer))!=-1){
                fos.write(b);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        long end = System.currentTimeMillis();
        System.out.println("方式二复制文件耗时："+(end-start) + "ms");
    }


    // 字节输入输出缓冲流以一个字节为单位复制文件
    public static void copy03(){
        long start = System.currentTimeMillis();

        try(
                FileInputStream fis = new FileInputStream(FILE_PATH);
                BufferedInputStream bis = new BufferedInputStream(fis);
                FileOutputStream fos = new FileOutputStream(PATH+"03.mp4");
                BufferedOutputStream bos = new BufferedOutputStream(fos);
        ){

            int b;
            while ((b = bis.read())!=-1){
                bos.write(b);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        long end = System.currentTimeMillis();
        System.out.println("方式三复制文件耗时："+(end-start)/1000.0 + "秒");
    }

    // 字节输入输出缓冲流以字节数组为单位复制文件
    public static void copy04(){
        long start = System.currentTimeMillis();

        try(
                FileInputStream fis = new FileInputStream(FILE_PATH);
                BufferedInputStream bis = new BufferedInputStream(fis);
//                BufferedInputStream bis = new BufferedInputStream(fis,32*1024); // 32KB测试
                FileOutputStream fos = new FileOutputStream(PATH+"04.mp4");
                BufferedOutputStream bos = new BufferedOutputStream(fos);
//                BufferedOutputStream bos = new BufferedOutputStream(fos,32*1024); // 32KB测试
        ){

            byte[] buffer = new byte[1024];
//            byte[] buffer = new byte[1024*8]; //8KB
//            byte[] buffer = new byte[1024*32]; //32KB
            int b;
            while ((b = bis.read(buffer))!=-1){
                bos.write(b);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        long end = System.currentTimeMillis();
        System.out.println("方式四复制文件耗时："+(end-start) + "ms");
    }

}
